package cn.signalpha.modules.schedule.task;

import cn.hutool.core.date.DateUtil;
import cn.signalpha.common.cache.ConfigCache;
import cn.signalpha.common.cache.ConfigKeys;
import cn.signalpha.common.dto.ConfigDTO;
import cn.signalpha.common.utils.Arith;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.modules.com.dto.WalletDTO;
import cn.signalpha.modules.com.entity.enums.WalletSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletTypeEnum;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.shop.entity.CouponUser;
import cn.signalpha.modules.shop.entity.Order;
import cn.signalpha.modules.shop.entity.OrderSettle;
import cn.signalpha.modules.shop.entity.enums.OrderStatusEnum;
import cn.signalpha.modules.shop.service.CouponUserService;
import cn.signalpha.modules.shop.service.OrderService;
import cn.signalpha.modules.shop.service.OrderSettlePlaceService;
import cn.signalpha.modules.shop.service.OrderSettleService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 订单任务
 *
 * @author signalpha
 */
@AllArgsConstructor
@Component("orderTask")
public class OrderTask implements ITask {

	private final UserService userService;
	private final OrderService orderService;
	private final CouponUserService couponUserService;
	private final OrderSettleService orderSettleService;
	private final OrderSettlePlaceService orderSettlePlaceService;

	@Override
	public void run(String params){
		Date date = new Date();
		ConfigDTO.ShopDTO config = ConfigCache.getObject(ConfigKeys.SHOP, ConfigDTO.ShopDTO.class);

		//未付款订单取消，补偿操作
		if(ObjectUtil.isNotEmpty(config.getClose())){
			Date dateTime = DateUtil.offsetHour(date, -config.getClose());
			orderService.list(Wrappers.<Order>query().lambda().eq(Order::getOrderStatus, OrderStatusEnum.UN_PAY.getStatus()).le(Order::getCreateTime, dateTime)).forEach(order -> {
				orderService.cancelOrder(order.getId(), order.getUserId());
			});
		}

		//已发货订单自动确认收货
		if(ObjectUtil.isNotEmpty(config.getFinish())){
			Date dateTime = DateUtil.offsetDay(new Date(), -config.getFinish());
			orderService.list(Wrappers.<Order>query().lambda().eq(Order::getOrderStatus, OrderStatusEnum.SEND_OUT.getStatus()).le(Order::getSendTime, dateTime)).forEach(order -> {
				orderService.updateById(Order.builder().id(order.getId()).orderStatus(OrderStatusEnum.SUCCESS.getStatus()).finishTime(date).build());
			});
		}

		//过了维权期的订单，进入结算动作
		Date dateTime = DateUtil.offsetDay(date, -config.getRefund());
		orderService.list(Wrappers.<Order>query().lambda().eq(Order::getOrderStatus, OrderStatusEnum.SUCCESS.getStatus()).eq(Order::getRefundStatus, 0).eq(Order::getSettleStatus, 0).le(Order::getFinishTime, dateTime)).forEach(order -> {
			orderService.updateById(Order.builder().id(order.getId()).settleStatus(1).settleTime(dateTime).build());
			//商户结算单
			OrderSettle orderSettle = orderSettleService.getByOrderNo(order.getOrderNo());
			if(orderSettle.getSettleStatus() == 0){
				orderSettleService.settleOrder(orderSettle.getId());
			}

			//佣金结算单
			orderSettlePlaceService.listByOrderNo(order.getOrderNo()).forEach(orderSettlePlace -> {
				if(orderSettlePlace.getSettleStatus() == 0){
					orderSettlePlaceService.settleOrder(orderSettlePlace.getId());
				}
			});

			//赠送积分
			if(order.getOrderPrice() > 0){
				int amount = (int) Math.ceil(order.getOrderPrice());
				int times = (int) Arith.div(amount, config.getIntegralPayMoney());
				double totalAmount = Arith.mul(times, config.getIntegralAward());
				if(totalAmount > 0){
					userService.updateUserIntegral(WalletDTO.builder()
						.userId(order.getUserId())
						.amount(totalAmount)
						.type(WalletTypeEnum.ADD.getType())
						.sourceId(order.getOrderNo())
						.sourceType(WalletSourceEnum.GOODS.getType())
						.remark("购买" + order.getGoodsName())
						.build());
				}
			}
		});

		//把过期优惠券失效掉
		couponUserService.update(Wrappers.<CouponUser>lambdaUpdate().set(CouponUser::getStatus, 2).eq(CouponUser::getStatus, 0).le(CouponUser::getEndTime, date));
	}

}
